#pragma once

#include <vector>
#include <cstdint>
#include <cmath>
#include <memory>

#include "rtda/heap/object.h"

namespace jvm {
namespace heap {

class Object;

struct Slot {
    int32_t num = 0;
    ObjectPtr pRef;

    Slot() : num(0), pRef(nullptr) {}
    Slot(const int& n, ObjectPtr ref) : num(n), pRef(ref) {}

    Slot(const Slot& other) = default;
    Slot& operator=(const Slot& other) = default;

    Slot(Slot&& other)noexcept = default;
    Slot& operator=(Slot&& other)noexcept = default;
};

class Slots {
private:
    std::vector<Slot> m_slots;

public:
    Slots(uint32_t slotCount);

    Slots(const Slots&) = default;
    Slots& operator=(const Slots&) = default;
    Slots(Slots&&)noexcept = default;
    Slots& operator=(Slots&&)noexcept = default;
    
    // Primitive type operations
    void setInt(uint32_t index, int32_t val);
    int32_t getInt(uint32_t index) const;
    
    void setFloat(uint32_t index, float val);
    float getFloat(uint32_t index) const;
    
    void setLong(uint32_t index, int64_t val);
    int64_t getLong(uint32_t index) const;
    
    void setDouble(uint32_t index, double val);
    double getDouble(uint32_t index) const;
    
    // Reference type operations
    void setRef(uint32_t index, ObjectPtr pRef);
    ObjectPtr getRef(uint32_t index) const;

    std::vector<Slot>& getSlots();
};

} // namespace heap
} // namespace jvm
